package own.stu.jobgib.playown.util.ftp;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.net.ftp.FtpClient;
import sun.net.ftp.FtpProtocolException;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;

public abstract class AbstractFtpCommand<P extends BaseParameter, R> implements FtpCommand<P, R>{

    protected static transient Logger log = LoggerFactory.getLogger(AbstractFtpCommand.class);

    protected P parameter;

    protected final static int BUFF_SIZE = 1024;

    /**
     * FTP 服务器地址IP地址
     */
    private static final String host = "192.168.1.131"; //OccPropertiesLoaderUtils.getValue("sftp.ip").toString();
    /**
     * FTP 端口
     */
    private static final int port = 21; // Integer.valueOf(OccPropertiesLoaderUtils.getValue("sftp.port").toString()).intValue();
    /**
     * FTP 登录用户名
     */
    private static final String username = "chen"; //OccPropertiesLoaderUtils.getValue("sftp.username").toString();
    /**
     * FTP 登录密码
     */
    private static final String password = "lock"; //OccPropertiesLoaderUtils.getValue("sftp.password").toString();

    @Override
    public R execute() throws Exception{
        checkParameter(parameter);

        FtpClient ftpClient = connect(parameter.getRemotePath());
        parameter.setFtpClient(ftpClient);

        R result = null;
        try {
            result = operate(parameter);
        }finally {
            disconnect(ftpClient);
        }
        return result;
    }

    protected abstract R operate(P parameter);

    protected abstract void checkParameter(P parameter);

    /**
     * 连接到ftp服务器
     * @param remotePath
     * @return
     */
    @SuppressWarnings("restriction")
    private static FtpClient connect(String remotePath) {
        FtpClient ftpClient = FtpClient.create();
        SocketAddress addr = new InetSocketAddress(host, port);
        try {
            ftpClient.connect(addr);
            ftpClient.login(username, password.toCharArray());
            ftpClient.setBinaryType();
            if (remotePath != null && remotePath.length() != 0) {
                // 把远程系统上的目录切换到参数path所指定的目录
                String[] paths = remotePath.split("/");
                for (String path : paths) {
                    if (path.length() == 0) {
                        continue;
                    }
                    try {
                        ftpClient.changeDirectory(path);
                    } catch (FtpProtocolException ex) {
                        ftpClient.makeDirectory(path);
                        ftpClient.changeDirectory(path);
                    }
                }
            }
            return ftpClient;
        } catch (Exception ex) {
            if (ftpClient != null) {
                disconnect(ftpClient);
            }
            throw new RuntimeException(ex);
        }
    }

    /**
     * 断开与ftp服务器连接
     * @param ftpClient
     */
    private static void disconnect(FtpClient ftpClient) {
        try {
            if (ftpClient != null) {
                ftpClient.close();
            }
            log.info("ftpClient is disconnect");
        } catch (IOException e) {
            log.error("ftp close throws Exception", e);
            throw new RuntimeException(e);
        }
    }
}
